home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgramD2.iso
/
Borland
/
Borland C++ V5.02
/
DOCVIEW.PAK
/
ODLISTVW.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-06
|
11KB
|
452 lines
//----------------------------------------------------------------------------
// ObjectWindows
// Copyright (c) 1993, 1995 by Borland International, All Rights Reserved
//
// Implements class TODListView
//----------------------------------------------------------------------------
#include <owl/pch.h>
#include <owl/docmanag.h>
#include <owl/filedoc.h>
#include <owl/inputdia.h>
#include <stdio.h>
#include "odlistbx.h"
#include "odlistvw.rc"
// class TODListView
// ~~~~~ ~~~~~~~~~~~
class _DOCVIEWCLASS TODListView : public TODListBox, public TView {
public:
TODListView(TDocument& doc, TWindow* parent = 0);
~TODListView();
static const char far* StaticName() {return "OD List View";} // put in resource
bool DirtyFlag;
// Overridden virtuals from TView
//
const char far* GetViewName() {return StaticName();}
TWindow* GetWindow() {return (TWindow*)this;}
bool SetDocTitle(const char far* docname, int index)
{return TODListBox::SetDocTitle(docname, index); }
// Overridden virtuals from TWindow
//
bool Create();
uint EvGetDlgCode(MSG far*);
bool CanClose() {return TODListBox::CanClose() && Doc->CanClose();}
protected:
long Origin;
bool LoadData(int top, int sel);
// Message response functions
//
void CmEditUndo();
void CmEditCut();
void CmEditCopy();
void CmEditPaste();
void CmEditDelete();
void CmEditClear();
void CmEditAdd();
void CmEditItem();
// void CmLineIndent();
// void CmLineUnindent();
bool VnCommit(bool force);
bool VnRevert(bool clear);
bool VnIsWindow(HWND hWnd) {return GetHandle() == hWnd;}
bool VnIsDirty() {return DirtyFlag;}
bool VnDocClosed(int omode);
void EvDestroy();
void CmSelChange() {} // to prevent interpreting as unprocessed accelerator
DECLARE_RESPONSE_TABLE(TODListView);
DECLARE_STREAMABLE(,TODListView,1);
};
//
// Last virtual line appended to list
//
const char VirtualLastLineStr[] = "---";
DEFINE_RESPONSE_TABLE1(TODListView, TODListBox)
EV_COMMAND(CM_ODLISTUNDO, CmEditUndo),
EV_COMMAND(CM_ODLISTCUT, CmEditCut),
EV_COMMAND(CM_ODLISTCOPY, CmEditCopy),
EV_COMMAND(CM_ODLISTPASTE, CmEditPaste),
EV_COMMAND(CM_ODLISTCLEAR, CmEditClear),
EV_COMMAND(CM_ODLISTDELETE, CmEditDelete),
EV_COMMAND(CM_ODLISTADD, CmEditAdd),
EV_COMMAND(CM_ODLISTEDIT, CmEditItem),
EV_WM_GETDLGCODE,
EV_WM_DESTROY,
EV_NOTIFY_AT_CHILD(LBN_DBLCLK, CmEditItem),
EV_NOTIFY_AT_CHILD(LBN_SELCHANGE, CmSelChange),
EV_VN_DOCCLOSED,
EV_VN_ISWINDOW,
EV_VN_ISDIRTY,
EV_VN_COMMIT,
EV_VN_REVERT,
END_RESPONSE_TABLE;
DEFINE_DOC_TEMPLATE_CLASS(TFileDocument, TODListView, ODLBTemplate);
ODLBTemplate odBinTpl("ODListBox, All files","*.*", 0, "TXT",dtAutoDelete);
ODLBTemplate odTxtTpl("ODStrings, All files","*.*", 0, "TXT",dtAutoDelete);
TODListView::TODListView(TDocument& doc, TWindow* /*parent*/)
:
TView(doc),
TODListBox((int)GetNextViewId()),
Origin(0),
DirtyFlag(false)
{
Attr.Style &= ~(WS_BORDER | LBS_SORT);
Attr.Style |= (WS_HSCROLL | LBS_NOINTEGRALHEIGHT);
if (doc.GetTemplate() == &odTxtTpl)
Attr.Style |= LBS_HASSTRINGS;
Attr.AccelTable = IDA_ODLISTVIEW;
SetViewMenu(new TMenuDescr(IDM_ODLISTVIEW,0,1,0,0,0,1));
}
bool
TODListView::LoadData(int top, int sel)
{
CmEditClear();
DeleteString(0);
DirtyFlag = false;
istream* inStream;
if ((inStream = Doc->InStream(ios::in)) == 0)
return false;
for (;;) {
char buf[100+1];
inStream->getline(buf, sizeof(buf)-1);
if (!inStream->gcount() && !inStream->good())
break; // if EOF or error
char* str;
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
str = buf;
}
else {
str = new char[strlen(buf)+1];
strcpy(str, buf);
}
AddString(str);
}
AddString(VirtualLastLineStr);
SetSelIndex(top);
SetSelIndex(sel);
delete inStream; // close file in case process switch
return true;
}
bool
TODListView::Create()
{
DirtyFlag = false;
TODListBox::Create(); // throws exception TXInvalidWindow
if (Doc->GetDocPath() == 0) {
CmEditClear(); // perform any clearing initialization
return true; // new file, no data to display
}
if (!LoadData(0, 0))
NotOK();
return true;
}
bool
TODListView::VnDocClosed(int omode)
{
int top;
int sel;
if (DirtyFlag == 2 || !(omode & ofWrite)) // make sure someone else's write
return false;
top = GetTopIndex();
sel = GetSelIndex();
LoadData(top, sel);
return true;
}
bool
TODListView::VnCommit(bool force)
{
if (!force && !DirtyFlag)
return true;
ostream* outStream;
if ((outStream = Doc->OutStream(ios::out)) == 0)
return false;
outStream->seekp(Origin);
char* buf = 0; // initialized only to prevent warning about use before def
int buflen = 0;
int count = GetCount();
for (int index = 0; index < count-1; index++) { // don't write last virtual line
int len;
char far* str;
if (Attr.Style & LBS_HASSTRINGS) {
len = GetStringLen(index);
}
else {
str = (char far*)GetItemData(index);
len = str ? strlen(str) : 0;
}
if (len != 0) {
if (len >= buflen) {
if (buflen != 0)
delete buf;
buf = new char[buflen = len+1];
}
if (Attr.Style & LBS_HASSTRINGS)
GetString(buf, index);
else
strcpy(buf, str);
*outStream << buf;
}
*outStream << '\n';
}
if (buflen != 0)
delete buf;
DirtyFlag = 2; // to detect our own close notification
delete outStream;
DirtyFlag = false;
return true;
}
bool
TODListView::VnRevert(bool clear)
{
if (!clear && Doc->GetDocPath() != 0)
return LoadData(0,0);
CmEditClear();
DirtyFlag = false;
return true;
}
uint
TODListView::EvGetDlgCode(MSG far*)
{
uint retVal = (uint)DefaultProcessing();
retVal |= DLGC_WANTCHARS;
return retVal;
}
void
TODListView::CmEditUndo()
{
MessageBox("Feature not implemented", "Undo", MB_OK);
}
void
TODListView::CmEditCut()
{
CmEditCopy();
CmEditDelete();
}
void
TODListView::CmEditCopy()
{
int index = GetSelIndex();
int count = GetCount();
if (count <= 1 || index >= count-1)
return;
char far* str;
int len;
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
len = GetStringLen(index);
}
else {
str = (char far*)GetItemData(index);
len = strlen(str);
}
TClipboard cb(*this);
if (cb.EmptyClipboard()) {
HANDLE cbhdl = ::GlobalAlloc(GHND, len+0+1);
char far* gbuf = (char far*)::GlobalLock(cbhdl);
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
GetString(gbuf, index);
}
else {
strcpy(gbuf, str);
}
::GlobalUnlock(cbhdl);
cb.SetClipboardData(CF_TEXT, cbhdl);
}
}
void
TODListView::CmEditPaste()
{
int index = GetSelIndex();
if (index < 0)
index = 0;
TClipboard cb(*this);
if (!cb)
return; // clipboard open by another window
HANDLE cbhdl = cb.GetClipboardData(CF_TEXT);
if (cbhdl) {
char far* text = (char far*)::GlobalLock(cbhdl);
char far* str;
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
str = text;
}
else {
str = new char[strlen(text)+1];
strcpy(str, text);
}
InsertString(str, index);
SetSelIndex(index+1);
DirtyFlag = true;
::GlobalUnlock(cbhdl);
}
}
void
TODListView::CmEditDelete()
{
int count = GetCount();
int index = GetSelIndex();
if (count <= 1 || index >= count-1)
return;
ODItemInfo item;
item.Hdc = ::GetDC(*this);
item.Index = index;
item.Data = (void far*)GetItemData(index);
item.State = 0;
GetItemInfo(item);
::ReleaseDC(*this, item.Hdc);
if (item.Extent.cx == MaxWidth)
SetHorizontalExtent(MaxWidth = 0); // force recalculate max width
if (!(Attr.Style & LBS_HASSTRINGS)) // strings not stored in list box
delete item.Data;
DeleteString(index);
SetSelIndex(index);
DirtyFlag = true;
}
void
TODListView::CmEditClear()
{
int count = GetCount();
if (count == 1)
return;
if (count) {
if (!(Attr.Style & LBS_HASSTRINGS)) // strings not stored in list box
for (int index = 0; index < count-1; index++)
delete[] (char far*)GetItemData(index);
ClearList();
DirtyFlag = true;
SetHorizontalExtent(MaxWidth = 0);
}
AddString(VirtualLastLineStr);
}
TODListView::~TODListView()
{
if (GetHandle())
CmEditClear();
}
void
TODListView::EvDestroy()
{
CmEditClear();
TWindow::EvDestroy();
}
static int linePrompt(TWindow* parent, int index, uint id, char far* buf,int buflen)
{
char msg[41];
sprintf(msg, string(*parent->GetModule(), IDS_ODLISTNUM).c_str(), index);
const char far* prompt = string(*parent->GetModule(), id).c_str();
return TInputDialog(parent, msg, prompt, buf, buflen).Execute();
}
void
TODListView::CmEditAdd()
{
char inputText[80];
*inputText = 0;
int index = GetSelIndex();
if (index < 0)
index = 0;
if (linePrompt(this,index+1,CM_ODLISTADD,inputText,sizeof(inputText))==IDOK) {
char far* str;
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
str = inputText;
}
else {
str = new char[strlen(inputText)+1];
strcpy(str, inputText);
}
InsertString(str, index);
SetSelIndex(index+1);
DirtyFlag = true;
}
}
void
TODListView::CmEditItem()
{
int index = GetSelIndex();
if (index < 0 || index >= GetCount()-1)
return;
int len;
char* inputText;
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
len = GetStringLen(index);
inputText = new char[len + 81];
GetString(inputText, index);
}
else {
char far* str = (char far*)GetItemData(index);
len = strlen(str);
inputText = new char[len + 81];
strcpy(inputText, str);
}
if (linePrompt(this,index+1,CM_ODLISTEDIT,inputText, len + 81)==IDOK) {
char far* str;
if (Attr.Style & LBS_HASSTRINGS) { // strings stored in list box
str = inputText;
}
else {
delete (char far*)GetItemData(index);
str = strnewdup(inputText);
}
DeleteString(index);
InsertString(str, index);
SetSelIndex(index);
DirtyFlag = true;
}
delete inputText;
}
IMPLEMENT_STREAMABLE2(TODListView, TODListBox, TView);
void *
TODListView::Streamer::Read(ipstream &is, uint32 /* version */) const
{
ReadBaseObject((TODListBox*)GetObject(), is);
ReadBaseObject((TView*)GetObject(), is);
is >> GetObject()->Origin;
GetObject()->DirtyFlag = false;
return GetObject();
}
void
TODListView::Streamer::Write(opstream &os) const
{
WriteBaseObject((TODListBox*)GetObject(), os);
WriteBaseObject((TView*)GetObject(), os);
os << GetObject()->Origin;
}